import axios from 'axios'
import { Notification, MessageBox, Message } from 'element-ui'
import { getToken } from '@/utils/validate.js'
import errorCode from '@/utils/errorCode'
import store from '@/store'

const request = axios.create({
  timeout: 20 * 1000,
  responseType: 'json',
  headers: { 'content-type': 'application/json;charset=UTF-8' },
  baseURL: process.env.VUE_APP_BASE_URL,
  withCredentials: false
})

// 请求拦截
request.interceptors.request.use(config => {
  const token = getToken()
  if (token) {
    config.headers['Authorization'] = 'Bearer ' + token
  } else {
    // 返回登录
  }
  return config
}, error => {
  console.log(error)
  Promise.reject(error)
})

// 响应拦截
request.interceptors.response.use(response => {
  const res = response.data
  // 未设置状态码则默认成功状态
  const code = res.errno || response.status
  // 获取错误信息
  const msg = res.errmsg || errorCode[code] || errorCode['default']
  switch (code) {
    // 请求成功
    case 300200 : case 200 :
      return res.data || res
    // 登录过期
    case 300403:
    case 300404:
      MessageBox.confirm(
        '登录状态已过期，您可以继续留在该页面，或者重新登录',
        '系统提示',
        {
          confirmButtonText: '重新登录',
          cancelButtonText: '取消',
          type: 'warning'
        }
      ).then(() => {
        store.dispatch('user/LogOut').then(() => {
          location.href = '/'
        })
      })
      break
    // 接口报错
    case 500:
      Message({
        message: msg,
        type: 'error'
      })
      return Promise.reject(new Error(msg))
    // 没有找到页面
    case 404:
      break
    // 没有权限
    case 300411:
      Message({
        message: '无操作权限',
        type: 'error',
        duration: 3 * 1000
      })
      break
    default:
      Notification.error({
        title: msg
      })
      return Promise.reject(msg)
  }
},
error => {
  let { message } = error
  if (message === 'Network Error') {
    message = '网关请求失败'
  } else if (message.includes('timeout')) {
    message = '系统接口请求超时'
  } else if (message.includes('Request failed with status code')) {
    message = '系统接口' + message.substr(message.length - 3) + '异常'
  }
  Message({
    message: message,
    type: 'error',
    duration: 3 * 1000
  })
  return Promise.reject(error)
}
)

function sendRequest(url, method, requestConfig, type) {
  const transUrl = url.replace(/^\//g, '')
  return function(params) {
    type = type || (method === 'get' ? 'params' : 'data')
    const basic = {
      method,
      url: transUrl,
      [type]: params || {}
    }
    const allConfig = Object.assign(
      {},
      basic,
      requestConfig || {}
    )
    return new Promise((res, rej) => {
      request(allConfig).then(json => {
        res(json)
      })
        .catch(error => {
          rej(error)
        })
    })
  }
}

const getMethod = {
  get: (url, config, type) => sendRequest(url, 'get', config, type),
  post: (url, config, type) => sendRequest(url, 'post', config, type),
  down: (url) => {
    return function(params) {
      return axios.get(url, { params: params, responseType: 'blob', baseURL: process.env.VUE_APP_BASE_URL, headers: { 'Authorization': 'Bearer ' + getToken() }}).then((res) => {
        const blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8' })
        const downloadElement = document.createElement('a')
        const href = window.URL.createObjectURL(blob)
        const contentDisposition = res.headers['content-disposition']
        const patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*')
        const result = patt.exec(contentDisposition)
        const filename = decodeURI(result[1])
        downloadElement.style.display = 'none'
        downloadElement.href = href
        downloadElement.download = filename
        document.body.appendChild(downloadElement)
        downloadElement.click()
        document.body.removeChild(downloadElement)
        window.URL.revokeObjectURL(href)
      })
    }
  }
}

export default getMethod
